﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using EI.SI;
using System.Net;
using System.Net.Sockets;
using System.IO;
using System.Diagnostics;

namespace Cliente
{
    class Program
    {


        static void Main(string[] args)
        {
            int port = 9999;

            IPAddress ip = IPAddress.Parse("127.0.0.1");


            //connects to server
            Console.Write("connecting to server");
            TcpClient tcpClient = new TcpClient();
            tcpClient.Connect(ip, port);
            Console.Write("ok");
            
            //get the stream to communicate with the client
            NetworkStream stream = tcpClient.GetStream();

            int n;
            ProtocolSI protocol = new ProtocolSI();
            byte[] msg;

            byte[] buffer = new byte[1024];
            string nomeficheiro = "happygrande.png";
            string ficheiro = "../../happygrande.png";
            

            ConsoleKeyInfo op;

            do{
                //read the user option
                Console.WriteLine("Qual a opcao?");
                Console.WriteLine("1- Enviar INT, 2- Enviar String, 3- envia happy.gif, 4-enviar fich grande, 9- Fim");
                op = Console.ReadKey();

                //send the "data" to server
                switch (op.Key)
                {
                    case ConsoleKey.D1:
                        msg = protocol.Make(ProtocolSICmdType.NORMAL, 123);
                        break;
                    case ConsoleKey.D2:
                        msg = protocol.Make(ProtocolSICmdType.DATA, "ola");
                        break;
                        
                    case ConsoleKey.D3:
                        // novo codigo -------------------------------------------------



                        FileStream fsRead = new FileStream(ficheiro, FileMode.Open);
                            //FileStream fsWrite = new FileStream(ficheiro, FileMode.Create, FileAccess.Write);

                            int n2;
                            n2 = fsRead.Read(buffer, 0, buffer.Length);
                            
                            msg = protocol.Make(ProtocolSICmdType.DATA, buffer);

                            /*
                             int n2;
                            while ((n2 = fsRead.Read(buffer, 0, buffer.Length)) != 0)
                            {
                                //fsWrite.Write(buffer, 0, n);
                                msg = protocol.Make(ProtocolSICmdType.DATA, "ola");

                            }
                              * */
                            fsRead.Close();
                        //novo codigo ----------------------------------
                        break;

                    case ConsoleKey.D4:
                        // ficheiro grande -----------------------------------------------------------------

                        msg = protocol.Make((ProtocolSICmdType)20, nomeficheiro); //ATENCAO !!! NOME DO FICHEIRO
                        stream.Write(msg, 0, msg.Length);

                        //recebe ACK
                         n = stream.Read(protocol.Buffer, 0, protocol.Buffer.Length);
                         //if (protocol.GetCmdType() == ProtocolSICmdType.ACK)
                         

                        //enviar ficheiro grande
                         FileStream fsRead2 = new FileStream(ficheiro, FileMode.Open);
                         int n3;
                         int cnt = 0;
                         while ((n3 = fsRead2.Read(buffer, 0, buffer.Length)) != 0)
                            {
                                Debug.WriteLine("cnd:"+ cnt +" n3: "+ n3);
                                cnt++;
                                msg = protocol.Make((ProtocolSICmdType)21, buffer);
                             //enviar para o servidor
                                stream.Write(msg, 0, msg.Length);

                             //a espera do ACK
                                n = stream.Read(protocol.Buffer, 0, protocol.Buffer.Length);
                                Debug.WriteLine("GetCmdType: " + protocol.GetCmdType());
                             //se receber ACK continuar
                                if (protocol.GetCmdType() != ProtocolSICmdType.ACK) break;
                                
                            }

                         msg = protocol.Make(ProtocolSICmdType.EOF);
                        //enviar FINAL DE FICHEIRO para o servidor
                         stream.Write(msg, 0, msg.Length);
                        
                        //msg = protocol.Make(ProtocolSICmdType.ACK);
                        // ficheiro grande --------------------------------------------------------------------
                        break;

                    case ConsoleKey.D9:
                        msg = protocol.Make(ProtocolSICmdType.EOT);
                        break;
                    default:
                        msg = protocol.Make(ProtocolSICmdType.EOF);
                        break;
                        
                }

                //send data
                //stream.Write(msg, 0, msg.Length);

                //n = stream.Read(protocol.Buffer, 0, protocol.Buffer.Length);

            } while(op.Key != ConsoleKey.D9);


            /*
            //send integer
            msg = protocol.Make(ProtocolSICmdType.DATA, 123);
            stream.Write(msg, 0, msg.Length);

            n = stream.Read(protocol.Buffer, 0, protocol.Buffer.Length);
            if (protocol.GetCmdType() != ProtocolSICmdType.ACK)
                throw new Exception("erro de protocolo");
            */

            stream.Close();
            tcpClient.Close();

            Console.WriteLine("end.");
            Console.ReadKey();
        }


      
    }
}
